package cn.xiaoke.damowang.order;

import cn.xiaoke.damowang.order.client.TestUserClient;
import cn.xiaoke.damowang.order.vo.BaseVoInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class UserNameUtil {
    public static final UserNameUtil userNameUtil = new UserNameUtil();
    private static TestUserClient userClient;

    @Autowired
    @Qualifier("cn.xiaoke.damowang.order.client.TestUserClient")
    public void setUserClient(TestUserClient userClient) {
        UserNameUtil.userClient = userClient;
    }

    private UserNameUtil(){}


    public static void setUserName(List<? extends BaseVoInfo> list){
        final List<Integer> ids = list.stream()
                .flatMap(item -> Stream.of(item.getCreateUser(), item.getUpdateUser()))
                .collect(Collectors.toList());
        final Map<Integer, String> map = userClient.listByIds(ids);
        list.forEach(item ->{
            item.setCreateUserName(map.get(item.getCreateUser()));
            item.setUpdateUserName(map.get(item.getUpdateUser()));
        });
    }

    public static <T> void setUserName(List<T> list,Function<T,Integer> getFun,BiConsumer<T, String> setFun){
        setUserName(list,new Info<>(getFun, setFun));
    }

    public static <T> void setUserName(List<T> list,Info<T>... infos){
        final List<Integer> ids = list.stream()
                .flatMap(item -> Arrays.stream(infos).map(info -> info.getFun.apply(item)))
                .filter(Objects::nonNull)
                .collect(Collectors.toList());
        final Map<Integer, String> map = userClient.listByIds(ids);
        list.forEach(item ->{
            Arrays.stream(infos).forEach(info -> info.setFun.accept(item,map.get(info.getFun.apply(item))));
        });
    }

    public static class Info<T>{
        private Function<T,Integer> getFun;
        private BiConsumer<T, String> setFun;

        public Info(Function<T, Integer> getFun, BiConsumer<T, String> setFun) {
            this.getFun = getFun;
            this.setFun = setFun;
        }
    }
}
